/*
 * HttpMessage.h
 *
 */

#ifndef HTTPMESSAGE_H_
#define HTTPMESSAGE_H_

#include "HttpBody.h"
#include <list>
#include <exception>

class HttpHeader;

#define HEADER_CONTENT_LENGTH "Content-Length"

class MessageException : public std::exception {
	private:
		std::string msg;
	public:
		explicit MessageException(const std::string& msg) throw();
		virtual ~MessageException() throw() {}
		const char* what() const throw() { return msg.c_str(); }
};

class HttpMessage {
	private:
		std::list<HttpHeader*> headers;
	public:
		HttpMessage();
		virtual ~HttpMessage();

		/**
		 * Agrega la referencia del header a la instancia.
		 * @param header Puntero a un header en el heap.
		 */
		void addHeader(HttpHeader* header);

		/**
		 * Remueve el header con el nombre pasado si existe.
		 * @param name Nombre del header a remover.
		 * @throw MessageException En caso que no exista el header.
		 */
		void removeHeader(const std::string& name);

		/**
		 * Devuelve el valor del header buscado si este existe.
		 * @param name Nombre del header a buscar.
		 * @throw MessageException En caso que no exista el header.
		 */
		std::string getHeader(const std::string& name) const;

		/**
		 * Devuelve una referencia constante a los headers contenidos.
		 */
		const std::list<HttpHeader*>& getAllHeaders() const;

		/**
		 * Métodos virtuales a definir por los herederos para el manejo de
		 * bodys de la instancia.
		 */
		virtual bool hasBody() const = 0;
		virtual HttpBody& getBody() const = 0;
		virtual void setBody(HttpBody* body) = 0;

		static const std::string CRLF;
		static const char CR = '\r';
		static const char LF = '\n';
		static const char TAB = '\t';
		static const char SP  = ' ';
		static const std::string WHITES;
};

#endif /* HTTPMESSAGE_H_ */
